package org.golang.godev.editors;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jface.text.rules.*;
import org.eclipse.jface.text.*;
import org.eclipse.swt.SWT;

/**
 * 
 * @author Qing Xu(joyeer.xuqing@gmail.com)
 *	Go source go scanner
 */
public class GoScanner extends RuleBasedScanner {

	private final static String[] KEYWORDS = {
		"break",     "default",   	"func",      "interface", "select",
		"case",      "defer",    	"go",        "map",       "struct",
		"chan",      "else",     	"goto",      "package",   "switch",
		"const",     "fallthrough", "if",        "range",     "type",
		"continue",  "for",         "import",    "return",    "var"
	} ;
	
	public final static String[] TYPES = {
		"uint8",
		"uint16",
		"uint32",
		"uint64",
		"int8",
		"int16",
		"int32",
		"int64",
		"float32",
		"float64",
		"complex64",
		"complex128",
		"byte",
		"uint",
		"int",
		"float",
		"complex",
		"uintptr",
	} ;
	
	public final class GoWordDetector implements IWordDetector {

		@Override
		public boolean isWordPart(char c) {
			return Character.isJavaIdentifierPart(c) ;
		}

		@Override
		public boolean isWordStart(char c) {
			return Character.isJavaIdentifierStart(c);
		}
	}
	
	/**
	 * 
	 *
	 */
	public final class GoWhitespaceDetector implements IWhitespaceDetector {
		@Override
		public boolean isWhitespace(char c) {
			return Character.isWhitespace(c) ;
		}
	}
	
	public GoScanner(ColorManager colorManager) {
		
		IToken keywordToken = new Token(new TextAttribute(colorManager
				.getColor(ColorManager.KEYWORD), null, SWT.BOLD));
		IToken typeToken = new Token(new TextAttribute(colorManager.getColor(ColorManager.TYPES))) ;
		IToken commentToken = new Token(new TextAttribute(colorManager
				.getColor(ColorManager.COMMENT)));
		IToken stringToken = new Token(new TextAttribute(colorManager
				.getColor(ColorManager.STRING)));
		IToken defaultToken = new Token(new TextAttribute(colorManager
				.getColor(ColorManager.DEFAULT)));

		List<IRule> rules = new ArrayList<IRule>() ;
		
		rules.add(new EndOfLineRule("//", commentToken)); // 
		
		rules.add(new SingleLineRule("\"", "\"", stringToken, '\\')); //$NON-NLS-2$ //$NON-NLS-1$

		
		// Add generic whitespace rule.
		rules.add(new WhitespaceRule(new GoWhitespaceDetector()));

		// Add word rule for keywords, types, and constants.
		WordRule wordRule = new WordRule(new GoWordDetector(), defaultToken,
				true);
		
		for (String keyword : KEYWORDS)
			wordRule.addWord(keyword, keywordToken);
		
		for(String type : TYPES) {
			wordRule.addWord(type, typeToken) ;
		}
		
		rules.add(wordRule);
		setRules(rules.toArray(new IRule[rules.size()]));
		
	}
}
